package com.anycc.cloud.common.util;

import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.LinkedList;
import java.util.List;

/**
 * jpa dynamic query
 */
public class DynamicQuery <T>{

    /** dynamic query
     * @param f QuartConsumer
     * @return Specification
     */
    public Specification<T> build(QuartConsumer<List<Predicate>, Root<T>, CriteriaQuery<?>, CriteriaBuilder> f){
        return (Specification<T>) (root, query, cb) -> {
            List<Predicate> predicateList = new LinkedList<>();
            f.accept(predicateList, root ,query, cb);
            return cb.and(predicateList.toArray(new Predicate[predicateList.size()]));
        };
    }

    /** FP interface for quart args consumer
     * @param <T> T
     * @param <U> U
     * @param <V> V
     * @param <W> W
     */
    public interface QuartConsumer<T, U, V, W> {
        void accept(T t, U u, V v, W w);
    }
}
